﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using FlickrNet;
using System.Configuration;


namespace FlickrPaper.handler
{
    /// <summary>
    /// Summary description for RetrieveFlickrImageashx
    /// </summary>
    public class RetrieveFlickrImage : IHttpHandler
    {

        public void ProcessRequest(HttpContext context)
        {
            context.Response.ContentType = "text/plain";

            Flickr flickr = new Flickr(
                ConfigurationManager.AppSettings["FlickrApiKey"].ToString(),
                ConfigurationManager.AppSettings["FlickrSharedSecret"].ToString());
                // ConfigurationManager.AppSettings["FlickrToken"].ToString()); // Include this as the 3rd param to access private photos

            string set = setOptionValue(context, "set");
            string tags = setOptionValue(context, "tags");
            string returnInfo = ConfigurationManager.AppSettings["flickrDefault"].ToString();

            if (context.Request.QueryString.Count > 0)
            {
                switch (context.Request.QueryString["direction"])
                {
                    case "random":
                        returnInfo = Random(flickr, set, tags);
                        break;
                    case "back":
                        returnInfo = NextPhoto(flickr, false, context.Request.QueryString["current"], set, tags);
                        break;
                    case "forward":
                        returnInfo = NextPhoto(flickr, true, context.Request.QueryString["current"], set, tags);
                        break;
                    case "info":
                        returnInfo = getImageInfo(flickr, context.Request.QueryString["current"], set, tags);
                        break;
                }
            }

            context.Response.Write(returnInfo);

        }
        // -----------------------------------------------------------------------------------------------------------------------------------------------------
        /// <summary>
        /// 
        /// </summary>
        /// <param name="context">http context</param>
        /// <param name="option">forward, backward</param>
        /// <returns></returns> 
        // -----------------------------------------------------------------------------------------------------------------------------------------------------
        private string setOptionValue(HttpContext context, string option)
        {
            string optionSetting = "FlickrDefault" + option;
            string returnValue = ConfigurationManager.AppSettings[optionSetting].ToString();
            if (context.Request.QueryString[option] != "" && context.Request.QueryString[option] != null) returnValue = context.Request.QueryString[option];
            return returnValue;
        }

        private string Random(Flickr flickr, string set, string tags)
        {
            PhotoCollection webpaper = new PhotoCollection();
            Random randomNumber = new Random();
            if (tags == "") webpaper = retrievePhotosFromSet(flickr, set);
            else webpaper = retrievePhotosFromTags(flickr, tags);
            return webpaper.ElementAt(randomNumber.Next(webpaper.Count - 1)).LargeUrl.ToString();
        }

        private string NextPhoto(Flickr flickr, bool forward, string current, string set, string tags)
        {
            int index = 0;
            PhotoCollection webpaper = new PhotoCollection();
            if (tags == "") webpaper = retrievePhotosFromSet(flickr, set);
            else webpaper = retrievePhotosFromTags(flickr, tags);

            foreach (Photo photo in webpaper)
                if (photo.LargeUrl != current) index++; else break;

            if (forward)
                if (index == (webpaper.Count - 1)) index = 0; else index++;
            else
                if (index == 0) index = webpaper.Count - 1; else index--;

            return webpaper.ElementAt(index).LargeUrl.ToString();
        }

        private PhotoCollection retrievePhotosFromSet(Flickr flickr, string set)
        {
            PhotosetPhotoCollection photoset = flickr.PhotosetsGetPhotos(set);
            PhotoCollection webpaper = new PhotoCollection();
            foreach (Photo photo in photoset) webpaper.Add(photo);
            return webpaper;
        }

        private PhotoCollection retrievePhotosFromTags(Flickr flickr, string tags)
        {
            PhotoSearchOptions searchOptions = new PhotoSearchOptions("me");
            searchOptions.Tags = tags;
            searchOptions.PerPage = 1000;
            PhotoCollection webpaper = flickr.PhotosSearch(searchOptions);
            return webpaper;
        }

        private string getImageInfo(Flickr flickr, string currentLargeURL, string set, string tags)
        {
            PhotoCollection webpaper = new PhotoCollection();
            string photoID = "";
            int index = 0;
            if (tags == "") webpaper = retrievePhotosFromSet(flickr, set);
            else webpaper = retrievePhotosFromTags(flickr, tags);

            foreach (Photo iphoto in webpaper)
            {
                if (iphoto.LargeUrl == currentLargeURL)
                {
                    photoID = iphoto.PhotoId;
                    break;
                }
                index++;
            }

            Photo photo = webpaper.ElementAt(index);
            ExifTagCollection exif = flickr.PhotosGetExif(photoID);

            string make = "", model = "", exposure = "", iso = "", datetime = "", aperture = "";

            foreach (ExifTag tag in exif)
            {
                switch (tag.Label)
                {
                    case "Make":
                        make = tag.Raw;
                        break;
                    case "Model":
                        model = tag.Raw;
                        break;
                    case "Exposure":
                        exposure = tag.Raw;
                        break;
                    case "ISO Speed":
                        iso = tag.Raw;
                        break;
                    case "ISO":
                        iso = tag.Raw;
                        break;
                    case "Aperture":
                        aperture = tag.Raw;
                        break;
                    case "Date and Time (Original)":
                        datetime = tag.Raw;
                        break;
                }
            }

            PhotoInfo info = flickr.PhotosGetInfo(photoID);
            string description = info.Description;

            string imageInfo = "<ul>";
            imageInfo += "<li><strong>Title:</strong> " + photo.Title + "</li>";
            imageInfo += "<li><strong>Caption:</strong> " + description + "</li>";
            imageInfo += "<li><strong>Camera:</strong> " + make + " " + model + "</li>";
            imageInfo += "<li><strong>Exposure:</strong> " + exposure + "</li>";
            imageInfo += "<li><strong>Aperture:</strong> " + aperture + "</li>";
            imageInfo += "<li><strong>ISO:</strong> " + iso + "</li>";
            imageInfo += "<li><strong>DateTime:</strong> " + datetime + "</li>";
            imageInfo += "<li><strong><a href=\"" + photo.WebUrl.ToString() + "\">View on Flickr</a></strong></li>";
            imageInfo += "</ul>";

            return imageInfo;
        }
        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
}